#include "settingsdialog.h"
#include <QMessageBox>
#include <QFile>
#include <QTextStream>
#include <QDir>
#include <QStandardPaths>

SettingsDialog::SettingsDialog(QWidget *parent)
    : QDialog(parent)
{
    setupUI();
    loadSettings();
    
    connect(buttonBox, &QDialogButtonBox::accepted, this, &SettingsDialog::accept);
    connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
    connect(applyButton, &QPushButton::clicked, this, &SettingsDialog::applySettings);
}

SettingsDialog::~SettingsDialog()
{
}

void SettingsDialog::setupUI()
{
    setWindowTitle(tr("设置"));
    setMinimumWidth(400);
    
    // Create form layout for settings
    QFormLayout *monitoringLayout = new QFormLayout;
    
    checkIntervalSpinBox = new QSpinBox;
    checkIntervalSpinBox->setRange(1, 300);
    checkIntervalSpinBox->setSuffix(tr(" 秒"));
    monitoringLayout->addRow(tr("检查间隔:"), checkIntervalSpinBox);
    
    highFreqThresholdSpinBox = new QSpinBox;
    highFreqThresholdSpinBox->setRange(1, 100);
    highFreqThresholdSpinBox->setSuffix(tr(" %"));
    monitoringLayout->addRow(tr("高频率阈值:"), highFreqThresholdSpinBox);
    
    lowFreqThresholdSpinBox = new QSpinBox;
    lowFreqThresholdSpinBox->setRange(1, 100);
    lowFreqThresholdSpinBox->setSuffix(tr(" %"));
    monitoringLayout->addRow(tr("低频率阈值:"), lowFreqThresholdSpinBox);
    
    sustainedPeriodHighSpinBox = new QSpinBox;
    sustainedPeriodHighSpinBox->setRange(1, 300);
    sustainedPeriodHighSpinBox->setSuffix(tr(" 秒"));
    monitoringLayout->addRow(tr("高负载持续时间:"), sustainedPeriodHighSpinBox);
    
    sustainedPeriodLowSpinBox = new QSpinBox;
    sustainedPeriodLowSpinBox->setRange(1, 600);
    sustainedPeriodLowSpinBox->setSuffix(tr(" 秒"));
    monitoringLayout->addRow(tr("低负载持续时间:"), sustainedPeriodLowSpinBox);
    
    QGroupBox *monitoringGroup = new QGroupBox(tr("监控设置"));
    monitoringGroup->setLayout(monitoringLayout);
    
    // Frequency adjustment settings
    QFormLayout *freqLayout = new QFormLayout;
    
    freqReductionSpinBox = new QSpinBox;
    freqReductionSpinBox->setRange(1, 100);
    freqReductionSpinBox->setSuffix(tr(" %"));
    freqLayout->addRow(tr("降频幅度:"), freqReductionSpinBox);
    
    freqIncreaseSpinBox = new QSpinBox;
    freqIncreaseSpinBox->setRange(1, 100);
    freqIncreaseSpinBox->setSuffix(tr(" %"));
    freqLayout->addRow(tr("升频幅度:"), freqIncreaseSpinBox);
    
    targetFreqAfterReductionSpinBox = new QSpinBox;
    targetFreqAfterReductionSpinBox->setRange(10, 100);
    targetFreqAfterReductionSpinBox->setSuffix(tr(" %"));
    freqLayout->addRow(tr("降频后目标频率:"), targetFreqAfterReductionSpinBox);
    
    QGroupBox *freqGroup = new QGroupBox(tr("频率调整"));
    freqGroup->setLayout(freqLayout);
    
    // IO load threshold settings
    QFormLayout *ioLayout = new QFormLayout;
    
    ioCriticalThresholdSpinBox = new QSpinBox;
    ioCriticalThresholdSpinBox->setRange(1, 100);
    ioCriticalThresholdSpinBox->setSuffix(tr(" %"));
    ioLayout->addRow(tr("极端IO负载阈值:"), ioCriticalThresholdSpinBox);
    
    ioSevereThresholdSpinBox = new QSpinBox;
    ioSevereThresholdSpinBox->setRange(1, 100);
    ioSevereThresholdSpinBox->setSuffix(tr(" %"));
    ioLayout->addRow(tr("严重IO负载阈值:"), ioSevereThresholdSpinBox);
    
    ioHighThresholdSpinBox = new QSpinBox;
    ioHighThresholdSpinBox->setRange(1, 100);
    ioHighThresholdSpinBox->setSuffix(tr(" %"));
    ioLayout->addRow(tr("高IO负载阈值:"), ioHighThresholdSpinBox);
    
    QGroupBox *ioGroup = new QGroupBox(tr("IO负载阈值"));
    ioGroup->setLayout(ioLayout);
    
    // Log settings
    QFormLayout *logLayout = new QFormLayout;
    
    logFileLineEdit = new QLineEdit;
    logLayout->addRow(tr("日志文件:"), logFileLineEdit);
    
    maxLogSizeMBSpinBox = new QSpinBox;
    maxLogSizeMBSpinBox->setRange(1, 100);
    maxLogSizeMBSpinBox->setSuffix(tr(" MB"));
    logLayout->addRow(tr("最大日志大小:"), maxLogSizeMBSpinBox);
    
    maxLogFilesSpinBox = new QSpinBox;
    maxLogFilesSpinBox->setRange(1, 20);
    logLayout->addRow(tr("保留日志文件数:"), maxLogFilesSpinBox);
    
    QGroupBox *logGroup = new QGroupBox(tr("日志设置"));
    logGroup->setLayout(logLayout);
    
    // Button box
    buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    applyButton = new QPushButton(tr("应用"));
    buttonBox->addButton(applyButton, QDialogButtonBox::ApplyRole);
    
    // Main layout
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(monitoringGroup);
    mainLayout->addWidget(freqGroup);
    mainLayout->addWidget(ioGroup);
    mainLayout->addWidget(logGroup);
    mainLayout->addWidget(buttonBox);
    
    setLayout(mainLayout);
}

void SettingsDialog::loadSettings()
{
    // Default configuration file path
    QString configPath = "/opt/ohmylinux/cpu-scheduler/cpu-scheduler.conf";
    
    QFile file(configPath);
    if (!file.exists()) {
        // Set default values
        setCheckInterval(5);
        setHighFreqThreshold(80);
        setLowFreqThreshold(30);
        setSustainedPeriodHigh(10);
        setSustainedPeriodLow(60);
        setFreqReduction(25);
        setFreqIncrease(25);
        setTargetFreqAfterReduction(75);
        setIoCriticalThreshold(90);
        setIoSevereThreshold(80);
        setIoHighThreshold(70);
        setLogFile("/var/log/cpu-scheduler.log");
        setMaxLogSizeMB(5);
        setMaxLogFiles(5);
        return;
    }
    
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QMessageBox::warning(this, tr("错误"), tr("无法读取配置文件"));
        return;
    }
    
    QTextStream in(&file);
    QString line;
    while (!in.atEnd()) {
        line = in.readLine().trimmed();
        if (line.startsWith("#") || line.isEmpty()) {
            continue;
        }
        
        QStringList parts = line.split("=");
        if (parts.size() != 2) {
            continue;
        }
        
        QString key = parts[0].trimmed();
        QString value = parts[1].trimmed();
        
        // Remove quotes from value if present
        if (value.startsWith("\"") && value.endsWith("\"")) {
            value = value.mid(1, value.length() - 2);
        }
        
        bool ok;
        int intValue = value.toInt(&ok);
        
        if (key == "CHECK_INTERVAL") {
            setCheckInterval(ok ? intValue : 5);
        } else if (key == "HIGH_FREQ_THRESHOLD") {
            setHighFreqThreshold(ok ? intValue : 80);
        } else if (key == "LOW_FREQ_THRESHOLD") {
            setLowFreqThreshold(ok ? intValue : 30);
        } else if (key == "SUSTAINED_PERIOD_HIGH") {
            setSustainedPeriodHigh(ok ? intValue : 10);
        } else if (key == "SUSTAINED_PERIOD_LOW") {
            setSustainedPeriodLow(ok ? intValue : 60);
        } else if (key == "FREQ_REDUCTION") {
            setFreqReduction(ok ? intValue : 25);
        } else if (key == "FREQ_INCREASE") {
            setFreqIncrease(ok ? intValue : 25);
        } else if (key == "TARGET_FREQ_AFTER_REDUCTION") {
            setTargetFreqAfterReduction(ok ? intValue : 75);
        } else if (key == "IO_CRITICAL_THRESHOLD") {
            setIoCriticalThreshold(ok ? intValue : 90);
        } else if (key == "IO_SEVERE_THRESHOLD") {
            setIoSevereThreshold(ok ? intValue : 80);
        } else if (key == "IO_HIGH_THRESHOLD") {
            setIoHighThreshold(ok ? intValue : 70);
        } else if (key == "LOG_FILE") {
            setLogFile(value);
        } else if (key == "MAX_LOG_SIZE_MB") {
            setMaxLogSizeMB(ok ? intValue : 5);
        } else if (key == "MAX_LOG_FILES") {
            setMaxLogFiles(ok ? intValue : 5);
        }
    }
    
    file.close();
}

void SettingsDialog::saveSettings()
{
    QString configPath = "/opt/ohmylinux/cpu-scheduler/cpu-scheduler.conf";
    
    QFile file(configPath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QMessageBox::warning(this, tr("错误"), tr("无法写入配置文件"));
        return;
    }
    
    QTextStream out(&file);
    out << "# CPU调度优化配置文件\n";
    out << "# 修改后需要重启服务生效: sudo systemctl restart cpu-scheduler.service\n\n";
    
    out << "# 监控设置\n";
    out << QString("CHECK_INTERVAL=%1           # 检查间隔(秒)\n").arg(checkInterval());
    out << QString("HIGH_FREQ_THRESHOLD=%1     # 高频率阈值(%%)\n").arg(highFreqThreshold());
    out << QString("LOW_FREQ_THRESHOLD=%1      # 低频率阈值(%%)\n").arg(lowFreqThreshold());
    out << QString("SUSTAINED_PERIOD_HIGH=%1   # 高负载持续时间(秒)\n").arg(sustainedPeriodHigh());
    out << QString("SUSTAINED_PERIOD_LOW=%1    # 低负载持续时间(秒)\n\n").arg(sustainedPeriodLow());
    
    out << "# 频率调整\n";
    out << QString("FREQ_REDUCTION=%1          # 降频幅度(%%)\n").arg(freqReduction());
    out << QString("FREQ_INCREASE=%1           # 升频幅度(%%)\n").arg(freqIncrease());
    out << QString("TARGET_FREQ_AFTER_REDUCTION=%1  # 降频后目标频率(%%)\n\n").arg(targetFreqAfterReduction());
    
    out << "# IO负载阈值\n";
    out << QString("IO_CRITICAL_THRESHOLD=%1   # 极端IO负载(%%)\n").arg(ioCriticalThreshold());
    out << QString("IO_SEVERE_THRESHOLD=%1     # 严重IO负载(%%)\n").arg(ioSevereThreshold());
    out << QString("IO_HIGH_THRESHOLD=%1       # 高IO负载(%%)\n\n").arg(ioHighThreshold());
    
    out << "# 日志设置\n";
    out << QString("LOG_FILE=\"%1\"\n").arg(logFile());
    out << QString("MAX_LOG_SIZE_MB=%1         # 最大日志大小(MB)\n").arg(maxLogSizeMB());
    out << QString("MAX_LOG_FILES=%1           # 保留日志文件数\n").arg(maxLogFiles());
    
    file.close();
}

void SettingsDialog::accept()
{
    applySettings();
    QDialog::accept();
}

void SettingsDialog::applySettings()
{
    saveSettings();
    QMessageBox::information(this, tr("设置"), tr("配置已保存，重启服务后生效"));
}

// Getter methods
int SettingsDialog::checkInterval() const
{
    return checkIntervalSpinBox->value();
}

int SettingsDialog::highFreqThreshold() const
{
    return highFreqThresholdSpinBox->value();
}

int SettingsDialog::lowFreqThreshold() const
{
    return lowFreqThresholdSpinBox->value();
}

int SettingsDialog::sustainedPeriodHigh() const
{
    return sustainedPeriodHighSpinBox->value();
}

int SettingsDialog::sustainedPeriodLow() const
{
    return sustainedPeriodLowSpinBox->value();
}

int SettingsDialog::freqReduction() const
{
    return freqReductionSpinBox->value();
}

int SettingsDialog::freqIncrease() const
{
    return freqIncreaseSpinBox->value();
}

int SettingsDialog::targetFreqAfterReduction() const
{
    return targetFreqAfterReductionSpinBox->value();
}

int SettingsDialog::ioCriticalThreshold() const
{
    return ioCriticalThresholdSpinBox->value();
}

int SettingsDialog::ioSevereThreshold() const
{
    return ioSevereThresholdSpinBox->value();
}

int SettingsDialog::ioHighThreshold() const
{
    return ioHighThresholdSpinBox->value();
}

QString SettingsDialog::logFile() const
{
    return logFileLineEdit->text();
}

int SettingsDialog::maxLogSizeMB() const
{
    return maxLogSizeMBSpinBox->value();
}

int SettingsDialog::maxLogFiles() const
{
    return maxLogFilesSpinBox->value();
}

// Setter methods
void SettingsDialog::setCheckInterval(int value)
{
    checkIntervalSpinBox->setValue(value);
}

void SettingsDialog::setHighFreqThreshold(int value)
{
    highFreqThresholdSpinBox->setValue(value);
}

void SettingsDialog::setLowFreqThreshold(int value)
{
    lowFreqThresholdSpinBox->setValue(value);
}

void SettingsDialog::setSustainedPeriodHigh(int value)
{
    sustainedPeriodHighSpinBox->setValue(value);
}

void SettingsDialog::setSustainedPeriodLow(int value)
{
    sustainedPeriodLowSpinBox->setValue(value);
}

void SettingsDialog::setFreqReduction(int value)
{
    freqReductionSpinBox->setValue(value);
}

void SettingsDialog::setFreqIncrease(int value)
{
    freqIncreaseSpinBox->setValue(value);
}

void SettingsDialog::setTargetFreqAfterReduction(int value)
{
    targetFreqAfterReductionSpinBox->setValue(value);
}

void SettingsDialog::setIoCriticalThreshold(int value)
{
    ioCriticalThresholdSpinBox->setValue(value);
}

void SettingsDialog::setIoSevereThreshold(int value)
{
    ioSevereThresholdSpinBox->setValue(value);
}

void SettingsDialog::setIoHighThreshold(int value)
{
    ioHighThresholdSpinBox->setValue(value);
}

void SettingsDialog::setLogFile(const QString &value)
{
    logFileLineEdit->setText(value);
}

void SettingsDialog::setMaxLogSizeMB(int value)
{
    maxLogSizeMBSpinBox->setValue(value);
}

void SettingsDialog::setMaxLogFiles(int value)
{
    maxLogFilesSpinBox->setValue(value);
}